/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package lazydatamodels;

import entities.Music;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import sessions.MusicManager;
import util.Introspection;

/**
 *
 * @author Antoine Boulinguez et Shyn-Yuan Cheng
 */
public class LazyMusicDataModel extends LazyDataModel<Music> {

    private MusicManager musicManager = lookupMusicManagerBean();
    private List<Music> datasource;
            
    public LazyMusicDataModel() {
        datasource = musicManager.getAllMusics();
    }
    
    @Override
    public Music getRowData(String rowKey) {
        return musicManager.getMusic(Long.valueOf(rowKey));
    }

    @Override
    public Long getRowKey(Music music) {
        return music.getId();
    }

    @Override
    public List<Music> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
        // Get all musics and create result object
        List<Music> data = new ArrayList<Music>();
        //List<Music> datasource = musicManager.getAllMusics();

        // FILTER HANDLING
        // For each song, determine if we keep the song in the datatable of the view
        for (Music music : datasource) {
            boolean match = true;

            // for each filter used by the user
            for (Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
                try {
                    String filterProperty = it.next(); // property of Music entity
                    String filterValue = filters.get(filterProperty); // value to search
                    //System.out.println("FILTER SIZE : " + filters.size() + " filterProperty = " + filterProperty + " filterValue = " + filterValue);

                    // Determine if the propertyFilter is a global filter
                    //  a globalFilter is not a real property of the Song entity
                    if (filterProperty.equals("globalFilter")) {
                        if (music.getTitle().toLowerCase().startsWith(filterValue.toLowerCase())
                                || music.getArtist().getArtistName().toLowerCase().startsWith(filterValue.toLowerCase())
                                || music.getAlbum().getTitle().toLowerCase().startsWith(filterValue.toLowerCase())
                                || String.valueOf(music.getTotalTime()).toLowerCase().startsWith(filterValue.toLowerCase())) {
                            match = true;

                        } else {
                            match = false;
                            break;
                        }
                    } else {
                        String fieldValue = Introspection.getFieldFromObject(music, filterProperty);
                        //System.out.println("===== fieldValue : " + fieldValue);

                        if (filterValue == null || filterValue.equals("") || fieldValue.toLowerCase().startsWith(filterValue.toLowerCase())) {
                            match = true;
                        } else {
                            match = false;
                            break;
                        }
                    }

                } catch (Exception e) {
                    //e.printStackTrace();
                    match = false;
                }
            }

            if (match) {
                data.add(music);
            }

        }

        //sort
        if (sortField != null) {
            Collections.sort(data, new LazySorter(sortField, sortOrder));
        }

        //rowCount
        int dataSize = data.size();
        this.setRowCount(dataSize);

        //paginate
        if (dataSize > pageSize) {
            try {
                return data.subList(first, first + pageSize);
            } catch (IndexOutOfBoundsException e) {
                return data.subList(first, first + (dataSize % pageSize));
            }
        } else {
            return data;
        }
    }

    private MusicManager lookupMusicManagerBean() {
        try {
            Context c = new InitialContext();
            return (MusicManager) c.lookup("java:global/ProjetStreamingBoulinguezCheng/ProjetStreamingBoulinguezCheng-ejb/MusicManager!sessions.MusicManager");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }
}
